package com.cy.wenxinapi.service.impl;

import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cy.wenxinapi.aichat.AIChatService;
import com.cy.wenxinapi.entity.InterviewRecode;
import com.cy.wenxinapi.service.InterviewRecodeService;
import com.cy.wenxinapi.mapper.InterviewRecodeMapper;
import com.cy.wenxinapi.util.*;
import com.cy.wenxinapi.vo.InterviewParamsVo;
import com.cy.wenxinapi.vo.QAstr;
import com.cy.wenxinapi.vo.QuestionVo;
import com.gearwenxin.client.ernie.ErnieBot4Client;
import com.gearwenxin.entity.response.ChatResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author c
 * @description 针对表【interview_recode】的数据库操作Service实现
 * @createDate 2024-02-26 11:13:04
 */
@Service
@Slf4j
public class InterviewRecodeServiceImpl extends ServiceImpl<InterviewRecodeMapper, InterviewRecode>
        implements InterviewRecodeService {

    @Resource
    private InterviewRecodeMapper mapper;

    @Resource
    private AIChatService aiChatService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private InMemoryCacheSingleton memoryCacheSingleton;

    @Override
    public String generateInterviewID(InterviewParamsVo vo) {

        String uuid = "MS" + System.currentTimeMillis();
        vo.setInterviewId(uuid);
        redisTemplate.opsForValue().set("uuid-" + uuid, vo);

        generateNewQuestions(vo);
        return uuid;
    }

    void generateNewQuestions(InterviewParamsVo vo) {
        String uuid = vo.getInterviewId();
        // 为了节省时间，在创建简历时就使用异步线程去生成题目

//            开始生成该简历的提问
            log.info("开始生成该简历的提问" + vo.toString());
            StopWatch stopWatch = new StopWatch();
            stopWatch.start(); // 开始计时

            String questionPrompt = aiChatService.getQuestionPrompt(vo);
            String aiChatAnswer = aiChatService.getAiChatAnswer(questionPrompt);
            List<String> aiChatAnswerJSONList = aiChatService.getAiChatAnswerJSONList(aiChatAnswer);
            List<QuestionVo> objects = new ArrayList<>();
            for (String item : aiChatAnswerJSONList) {
                QuestionVo questionVo = new QuestionVo();
                if (item.contains("专业技能类")) {
                    questionVo.setType("专业技能");
                    questionVo.setColor("blue");
                    questionVo.setQuestion(item);
                    objects.add(questionVo);
                }else{
                    questionVo.setType("行为类");
                    questionVo.setColor("pink");
                    questionVo.setQuestion(item);
                    objects.add(questionVo);
                }
            }

            stopWatch.stop(); // 停止计时

            // 输出执行时间
            long time = stopWatch.getTotalTimeMillis(); // 获取执行时间，单位为毫秒
            System.out.println("代码运行时间: " + time + " ms");
            redisTemplate.opsForValue().set("questions-" + uuid, objects);

    }

    @Override
    public void commitquestionAnswer(InterviewRecode interviewRecode) {
        //此时获取题目和答案 将数据入库

        mapper.insert(interviewRecode);
    }


    @Override
    public Result updateQuestionAnswer(InterviewRecode interviewRecode) {
        Integer interviewIndex = interviewRecode.getInterviewIndex();
        String answer = interviewRecode.getAnswer();
        String question = interviewRecode.getQuestion();
        String interviewId = interviewRecode.getInterviewId();
        UpdateWrapper<InterviewRecode> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("interview_id", interviewId);
        updateWrapper.eq("interview_index", interviewIndex);
        updateWrapper.set("answer", answer);
        updateWrapper.set("question", question);
        int update = mapper.update(updateWrapper);
        if (update == 1) {
            return Result.ok();
        } else {
            return Result.error();
        }

    }

    @Resource
    private ErnieBot4Client ernieBot4Client;

    @Resource
    private InterviewRecodeMapper interviewRecodeMapper;

    @Override
    public R getResult(String msg, String interviewId) {

        if (StrUtil.isNotEmpty(msg)) {

//            if (StrUtil.isNotEmpty(interviewId)) {
//                //如果数据库已经有这个结果了,直接查询返回
//                InterviewRecode oneInterViewRecord = interviewRecodeMapper.getOneInterViewRecord(interviewId);
//                return R.ok(oneInterViewRecord.getChat());
//            }

            String promptBefore = "这是我进行模拟面试的记录，请根据回答情况进行评价，";

            String promptAfter = ",首先给出总分（满分100），然后每道题目分别给出评价和建议的回答。你回答的方式使用json格式，方便我提前评价内容，参考回答案例： {\n" +
                    "  \"total_score\": 80,\n" +
                    "  \"question_1\": {\n" +
                    "    \"score\": 90,\n" +
                    "    \"evaluation\": \"xxx\",\n" +
                    "  },...";
            Mono<ChatResponse> chatResponseMono = ernieBot4Client.chatSingle(promptBefore + msg + promptAfter);
            System.out.println(chatResponseMono);

            ChatResponse block = chatResponseMono.block();
            String result = block.getResult();
            String replace = result.replace("```json", "").replace("```", "");
            JSONObject jsonObject = JSON.parseObject(replace);

            List<QA> qas = JSON.parseArray(msg, QA.class);


            for (String key : jsonObject.keySet()) {

                if (key.startsWith("question_")) {
                    Integer prefix_index = Integer.valueOf(key.replace("question_", "")) - 1;

                    JSONObject questionObj = jsonObject.getJSONObject(key);
                    questionObj.put("question", qas.get(prefix_index).getQuestion());
                    questionObj.put("answer", qas.get(prefix_index).getAnswer());

                    InterviewRecode interviewRecode = new InterviewRecode();
                    interviewRecode.setAnswer(questionObj.getString("answer"));
                    interviewRecode.setQuestion(questionObj.getString("question"));
                    interviewRecode.setInterviewId(interviewId);


//                    interviewRecode
                }
            }

            return R.ok(jsonObject);


        } else {
            return R.error();
            // 当msg为空时，可以返回一个默认的ChatResponse实例、空响应或其他错误信息
//            return Mono.just(new ChatResponse("1", "1", "1", 1, 1, true, true, "1", null, "你找到我的bug了", null, null, null, null, null, null, null, null)); // 示例返回一个带有默认提示信息的ChatResponse实例
        }
    }


    @Override
    public void getResultUpdate(String jsonString, String interviewId) {

//        String question = "假设你现在是面试者，要面试【销售培训生】岗位，现在面试官问了这个问题：请简单介绍一下您过去两年作为Java开发的工作经历，包括您参与的项目和您在项目中的角色。 请你做出回答。";

        List<QA> qas = JSON.parseArray(jsonString, QA.class);
        for (QA qa : qas) {

            new Thread(() -> {
                String question = qa.getQuestion();
                String job = "销售培训生";
                String getPrefectAnswer = "假设你现在是面试者，要面试【%s】岗位，现在面试官问了这个问题：%s 请你做出回答。";
                String format = String.format(getPrefectAnswer, job, question);
                String aiChatAnswer = aiChatService.getAiChatAnswer(format);
                memoryCacheSingleton.put(interviewId + question, aiChatAnswer);
            }).start();
        }


    }

    @Override
    public Result getQuestionForInterview(String interviewId) throws InterruptedException {
//        List<String> questions = new ArrayList<>();
//        for (int i = 0; i < 100; i++) {
//            questions = (List<String>) redisTemplate.opsForValue().get("questions-" + interviewId);
//            if (ObjectUtil.isNotEmpty(questions)) {
//                break;
//            }else {
//                Thread.sleep(1000);
//            }
//        }
        List<String> questions = getQuestions(interviewId);

        return Result.ok(questions);
    }


    public List<String> getQuestions(String interviewId) {
        long startTime = System.currentTimeMillis();
        long timeout = TimeUnit.SECONDS.toMillis(100); // 设置总的超时时间（例如100秒）
        long sleepInterval = TimeUnit.SECONDS.toMillis(1); // 设置每次休眠间隔（例如1秒）

        while (true) {
            List<String> questions = (List<String>) redisTemplate.opsForValue().get("questions-" + interviewId);
            if (ObjectUtil.isNotEmpty(questions)) {
                return questions;
            }

            long currentTime = System.currentTimeMillis();
            if (currentTime - startTime > timeout) {
                break;
            }

            try {
                Thread.sleep(sleepInterval);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("Thread interrupted while waiting for questions", e);
            }
        }
        return null;
    }
    @Resource
    private RedisUtils redisUtils;
    @Override
    public Result getInterviewList() {
        List<InterviewParamsVo> valuesByPrefix = redisUtils.getValuesByPrefix("uuid-");

        return Result.ok(valuesByPrefix);
    }

    @Override
    public Result getInterviewResult(QAstr qAstr) {
        String interviewId = qAstr.getInterviewId();
        InterviewParamsVo vo = (InterviewParamsVo) redisTemplate.opsForValue().get("uuid-" + interviewId);
        String job = vo.getJob();
        List<QA> msg = qAstr.getMsg();
        List<QuestionVo> questionVoList = (List<QuestionVo>) redisTemplate.opsForValue().get("questions-" + interviewId);
        ArrayList<QuestionVo> result = new ArrayList<>();


        for (int i = 0; i < questionVoList.size(); i++) {
            QuestionVo questionVo = questionVoList.get(i);
            new Thread(() -> {
//                Advice answer（参考回答）  面试者身份
                String question = questionVo.getQuestion();
                String getPrefectAnswer = "假设你现在是面试者，要面试【%s】岗位，现在面试官问了这个问题：%s 请你做出回答。";
                String format = String.format(getPrefectAnswer, job, question);
                String aiChatAnswer = aiChatService.getAiChatAnswer(format);
                redisTemplate.opsForValue().set(qAstr.getInterviewId()+"-" + question + "-AdviceAnswer", aiChatAnswer);
//               Recommended answer       面试官身份

                String getRecommendedAnswer = "假设你现在是面试官，要面试【%s】岗位，你问了这个问题：%s 你最期待听到面试者从什么思路进行回答。";
                String format2 = String.format(getRecommendedAnswer, job, question);
                String aiChatAnswer2 = aiChatService.getAiChatAnswer(format2);
                redisTemplate.opsForValue().set(qAstr.getInterviewId()+"-" + question + "-RecommendedAnswer", aiChatAnswer2);
            }).start();
            questionVo.setIndex(i + 1);
            questionVo.setAnswer(msg.get(i).getAnswer());
            result.add(questionVo);
        }


        String getRecommendedAnswer = "我要面试【%s】岗位，完成了6道面试题，具体回答情况为：%s,请你根据我回答的情况给出0-100的评分，只需要给出一个分数，类似【总体：xx分】。";
        String feedback = String.format(getRecommendedAnswer, job, qAstr.getMsg());
        String aiChatAnswer = aiChatService.getAiChatAnswer(feedback);
        int rating = extractRating(aiChatAnswer);
        log.info("当前面试的结果：" + aiChatAnswer);



        new Thread(() -> {
            //重新生成题目
            redisTemplate.delete("questions-" + interviewId);
            generateNewQuestions(vo);
        }).start();


        return Result.ok(result).put("totalScore", rating);
    }

    public static int extractRating(String feedbackText) {
        log.info(feedbackText);
        Pattern pattern = Pattern.compile("总体：(\\d+)分");
        Matcher matcher = pattern.matcher(feedbackText);

        if (matcher.find()) {
            int score = Integer.parseInt(matcher.group(1));
            System.out.println("找到的评分是：" + score);
            return score;
        } else {
            System.out.println("未在文本中找到评分");
            return -1; // 或者返回一个默认值表示未能成功提取
        }


    }

    @Override
    public Result getBestAnswer(String question, String interviewId) {
//        String result = (String) redisTemplate.opsForValue().get(interviewId+"-" + question+"-AdviceAnswer");
        String result = getBestAnswerFromRedis(interviewId, question);

        return Result.ok(result);
    }

    public String getBestAnswerFromRedis(String interviewId, String question) {

        long startTime = System.currentTimeMillis();
        long timeout = TimeUnit.SECONDS.toMillis(100); // 设置总的超时时间（例如100秒）
        long sleepInterval = TimeUnit.SECONDS.toMillis(1); // 设置每次休眠间隔（例如1秒）

        while (true) {
            String result = (String) redisTemplate.opsForValue().get(interviewId + "-" + question + "-AdviceAnswer");
            if (StrUtil.isNotEmpty(result)) {
                return result;
            }

            long currentTime = System.currentTimeMillis();
            if (currentTime - startTime > timeout) {
                break;
            }

            try {
                Thread.sleep(sleepInterval);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("Thread interrupted while waiting for questions", e);
            }
        }
        return null;
    }


    @Override
    public Result getInterviewerAnswer(String question, String interviewId) {
//        String result = (String) redisTemplate.opsForValue().get("interviewerAnswer" + question+interviewId);
//        String result = (String) redisTemplate.opsForValue().get(interviewId+"-" + question+"-RecommendedAnswer");

        String result = getInterviewerAnswerFromRedis(interviewId, question);

        return Result.ok(result);
    }
    public String getInterviewerAnswerFromRedis(String interviewId, String question) {

        long startTime = System.currentTimeMillis();
        long timeout = TimeUnit.SECONDS.toMillis(100); // 设置总的超时时间（例如100秒）
        long sleepInterval = TimeUnit.SECONDS.toMillis(1); // 设置每次休眠间隔（例如1秒）

        while (true) {
            String result = (String) redisTemplate.opsForValue().get(interviewId+"-" + question+"-RecommendedAnswer");
            if (StrUtil.isNotEmpty(result)) {
                return result;
            }

            long currentTime = System.currentTimeMillis();
            if (currentTime - startTime > timeout) {
                break;
            }

            try {
                Thread.sleep(sleepInterval);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("Thread interrupted while waiting for questions", e);
            }
        }
        return null;
    }

    public static void main(String[] args) {
        String jsonString = "[{\"answer\":\"我作为Java开发工程师\",\"question\":\"请简单介绍一下您过去两年作为Java开发的工作经历，包括您参与的项目和您在项目中的角色。\"},{\"answer\":\"我熟悉Java 高并发\",\"question\":\"在您的Java开发工作中，您最擅长的技术栈是什么？能否给我一个具体的例子，说明您如何应用这些技术解决问题？\"},{\"answer\":\"高并发场景下多线程竞争，使用分布式锁解决\",\"question\":\"描述一下您在工作中遇到的一个技术难题，以及您是如何解决这个问题的。\"},{\"answer\":\"我是老大，他们听我的\",\"question\":\"在团队合作中，您是如何处理与其他开发人员的冲突或分歧的？请提供一个具体的例子。\"},{\"answer\":\"有，使用redis缓存提高效率\",\"question\":\"在您的项目中，是否有过性能优化的经历？如果有，请描述一下您是如何进行性能优化，以及优化后的效果如何。\"},{\"question\":\"您是如何保持自己的技术水平和行业动态的？请谈谈您最近学习的一项新技术，以及您是如何将它应用到实际工作中的。\"}]";

        List<QA> qas = JSON.parseArray(jsonString, QA.class);
        for (QA qa : qas) {

            String question = qa.getQuestion();
            String answer = qa.getAnswer();

            String job = "销售培训生";
            String getPrefectAnswer = "假设你现在是面试者，要面试【%s】岗位，现在面试官问了这个问题：%s 请你做出回答。";
            String format = String.format(getPrefectAnswer, job, question);
            System.out.println(format);

        }


        System.out.println(

        );
    }

    @Override
    public Result getOverallRating(String interviewID) {

        List<InterviewRecode> interviewRecodeList = mapper.getInterViewRecord(interviewID);
//        if (interviewRecodeList.size() <6) {
//            return Result.error();
//        }

        List<QA> collections = new ArrayList<>();
        for (InterviewRecode interviewRecode : interviewRecodeList) {
            QA qa = new QA();
            qa.setQuestion(interviewRecode.getQuestion());
            qa.setAnswer(interviewRecode.getAnswer());
            collections.add(qa);
        }

        String collectionStr = JSON.toJSONString(collections);

        String prompt = "这是一场面试中面试者的回答，请对回答结果进行评价,分别对每一道题目进行评价，包括意见补充，最后给出综合评价，并给出从不同角度的综合评分，" + collectionStr;

        String aiChatAnswer = aiChatService.getAiChatAnswer(prompt);


        return Result.ok(aiChatAnswer);


    }


}




